# Copyright (c) 2021 Presto Labs Pte. Ltd.
# Author: leon

import requests
from coin2.exchange.product_info import ProductInfoDefault
from coin2.exchange.symbology import SymbologyInfo
import json
import copy
import re


def instrument_to_web_format(instrument_data):
  web_data = []
  keyval = {}
  for item in instrument_data:
    if item['product_type'] != "PRODUCT_TYPE_PERPETUAL_SWAP":
      continue
    keyval["symbol"] = item["symbol"]
    keyval["productType"] = item["product_type"]
    keyval["positionUnit"] = item["position_unit"]
    keyval["quoteCurrency"] = item["quote_currency"]
    keyval["tickSize"] = item["tick_size"]
    keyval["unitOrderQty"] = item["unit_order_qty"]
    keyval["isInverse"] = item["is_inverse"]
    web_data.append(copy.deepcopy(keyval))

  return web_data


def add_extra_cover_raw_pi(data: json):
  data_dict = {}
  for item in data:
    symbol = item["symbol"]
    data_dict[symbol] = item

  extra = "python/coin2/support/product_info/prex/Futures.Prex.v1_raw.json"
  with open(extra) as fd:
    extra_data = json.load(fd)

  extra_raw_pi = instrument_to_web_format(extra_data)
  for info in extra_raw_pi:
    symbol = info["symbol"]
    data_dict[symbol] = info    # Use extra_dict to cover date_dict

  return data_dict

def add_extra_append_raw_pi(data: dict):
  extra_append_raw_pi = "python/coin2/support/product_info/prex/Futures.Prex.v1_raw_new.json"
  with open(extra_append_raw_pi) as fd:
    extra_data = json.load(fd)
  
  save_list = []
  extra_raw_pi = instrument_to_web_format(extra_data)
  for i, info in enumerate(extra_raw_pi):
    symbol = info["symbol"]
    if symbol in data:
      continue
    else:
      data[symbol] = info
      save_list.append(extra_data[i])

  with open(extra_append_raw_pi, "w+") as fd:
    json.dump(save_list, fd, indent=2)

  return data

def prex_pi_hand_updata():
  path = "python/coin2/support/product_info/prex/Prex_hand_update.json"
  with open(path) as fd:
    hand_data = json.load(fd)

  data = instrument_to_web_format(hand_data)
  return data


asset_multiplier_base_list = ["1000LUNC", "1000SHIB", "1000FLOKI", "1000PEPE", "1000XEC", "1000PEPE2"]

def ticksize_compensator(pi):
  base_update_map = {}
  symbol_update_map = {}

  tick_size = pi["price_ticksize"]
  native_base = pi["native_base"]
  if native_base in base_update_map:
    new_tick_size = base_update_map[native_base][1]
    return new_tick_size

  native_symbol = pi["native_symbol"]
  if native_symbol in symbol_update_map:
    new_tick_size = symbol_update_map[native_symbol][1]
    return new_tick_size

  return tick_size

def generate():
  mea = 'Futures.Prex.v1'
  me = 'Futures.Prex'
  default = ProductInfoDefault()
  symbol_info = SymbologyInfo()

  data = prex_pi_hand_updata()
  if (len(data) == 0):
    instrument_list_url = 'https://api.aqx.com/api/v1/instrument/list'
    # instrument_list_url = 'http://api.sandbox.prex.run/api/v1/instrument/list?isTradable=true'
    headers = requests.utils.default_headers()
    headers.update({"Origin": "https://aqx.com"})
    data = requests.get(instrument_list_url, headers=headers).json()['instruments']

  data = add_extra_cover_raw_pi(data)
  data = add_extra_append_raw_pi(data)
  pis = []
  for key, info in data.items():
    if info['productType'] != "PRODUCT_TYPE_PERPETUAL_SWAP":
      continue
    native_symbol = info['symbol']
    native_base = info['positionUnit']
    native_quote = info['quoteCurrency']
    base = symbol_info.native_to_norm_currency(mea, native_base)
    quote = symbol_info.native_to_norm_currency(mea, native_quote)
    symbol = "%s-%s.%s" % (base, quote, 'PERPETUAL')

    pi = dict(
        symbol=symbol,
        base=base,
        quote=quote,
        native_symbol=native_symbol,
        native_base=native_base,
        native_quote=native_quote,
        price_ticksize= float(info['tickSize']),
        qty_ticksize=float(info['unitOrderQty']),
        is_inverse=info['isInverse'],
        contract_value=float(1)
    )

    pi["price_ticksize"] = ticksize_compensator(pi)
    if "min_order_qty" in info:
      pi["min_qty"] = float(info["min_order_qty"])

    if "notionalMinOrderAmount" in info:
      # pi["min_amount"] = float(info["notionalMinOrderAmount"])
      pi["min_amount"] = 0 # does not check for mm acc 
      # ref https://prestolabs.slack.com/archives/C01RED2J2MT/p1688977106294089?thread_ts=1688977011.222519&cid=C01RED2J2MT

    if base in asset_multiplier_base_list:
      regex = "^[0-9]{2,}"
      result = re.search(regex, base)
      asset_multiplier = float(result.group(0))
      asset = base[len(result.group(0)):]
      pi["asset"] = asset
      pi["asset_multiplier"] = asset_multiplier

    pi = {**pi, **default.product_info(me, symbol)}
    pis.append(pi)

  pis = sorted(pis, key=lambda x: x['symbol'])
  return pis


def gen_coin1_constants():
  data = generate()
  data = convert_coin1_constants(data)
  return data


def convert_coin1_constants(data):
  symbol_list = [info['native_symbol'] for info in data]
  quote_currency_list = [info['native_quote'] for info in data]
  base_currency_list = [info['native_base'] for info in data]
  currency_list = base_currency_list + quote_currency_list
  res = {
      'symbol_list': list(set(symbol_list)),
      'base_currency_list': list(set(base_currency_list)),
      'quote_currency_list': list(set(quote_currency_list)),
      'currency_list': list(set(currency_list)),
  }
  return res


if __name__ == "__main__":
  import json
  print(json.dumps(generate(), indent=2))
